import { SignupDto } from '@/dtos/signup.dto';
import { EditProfileDto } from '@/dtos/editProfile.dto';
import { UserModel } from '@/database/models/user.model';
import { PhotoStatus } from '@/enums/photoEnums';
import type { UserInfo } from '@/typings/user';
import type { QueryUsersParams, DelUserPhotoParams } from './types/user.types';
import { UserStatus } from '@/enums/userEnums';

const populatePhotos = {
  path: 'photos',
  model: 'photos',
  match: {
    status: {
      $ne: PhotoStatus.deleted
    }
  }
};

export class UserService {
  // 根据账户查询用户
  static findUserByAcnt = async (acnt: string) => {
    const result = await UserModel
      .findOne({ account: acnt })
      .populate(populatePhotos).exec();
    const user = result ? result.toObject<UserInfo>() : null;
    return user;
  }

  // 创建一个新用户
  static createUser = async (dto: SignupDto) => {
    const newUser = new UserModel(dto);
    const result = await newUser.save();
    const json = result.toObject<UserInfo>();
    delete json.password;
    return json;
  }

  // 根据用户id查询用户
  static findUserById = async (uid: string) => {
    const result = await UserModel
      .findById(uid)
      .populate(populatePhotos).exec();
    return result ? result.toObject<UserInfo>() : null;
  }

  // 排除掉password
  static findUserByIdAndOmitPassword = async (uid: string) => {
    const user = await this.findUserById(uid);
    if (user) {
      delete user.password;
    }
    return user;
  }

  //检查用户是否存存在
  static checkUserExist = async (uid: string) => {
    const user = await this.findUserById(uid);
    return !!user?._id;
  }

  // 编辑用户信息
  static editUser = async (uid: string, update: EditProfileDto) => {
    await UserModel.updateOne(
      { _id: uid },
      { $set: update }
    ).exec();

    const user = await this.findUserById(uid);
    delete user.password;
    return user;
  }

  /**
   * 分页查询用户列表
  */
  static queryUsersByPage = async (params: QueryUsersParams) => {
    const { page = 1, pageSize = 10, filters, sorter } = params;
    const skipCount = (page - 1) * pageSize;

    let filter: Record<string, any> = {
      status: { $ne: UserStatus.deleted }
    };

    if (filters) {
      Object.keys(filters).forEach(key => {
        let val = filters[key];
        switch (key) {
          case 'nickName':
          case 'account': {
            val = { $regex: val, $options: 'i' };
            break;
          }
        }
        filter[key] = val;
      });
    }

    const total = await UserModel.countDocuments(filter);

    const result = await UserModel
      .find(filter)
      .sort(sorter)
      .skip(skipCount)
      .limit(pageSize)
      .populate(populatePhotos).exec();

    return {
      total,
      list: result as unknown as UserInfo[]
    };
  }

  static delUserPhoto = async (params: DelUserPhotoParams) => {
    const result = await UserModel.updateOne(
      { _id: params.userId },
      { $pull: { photos: params.photoId } }
    );
    return result;
  }
}
